home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WW3DKit / RIBParaboloid.m < prev    next >
Encoding:
Text File  |  1995-05-13  |  10.3 KB  |  416 lines

  1. // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
  2. // see COPYRIGHT for reuse legalities
  3. //
  4.  
  5. #import "RIBParaboloid.h"
  6. #import <stdio.h>
  7.  
  8.  
  9. @implementation RIBParaboloid
  10.  
  11. + initialize { return [RIBParaboloid setVersion:1], self; }
  12.  
  13. - (BOOL)hasBoundingBox { return YES; }
  14.  
  15. - init
  16. {
  17.   [super init];
  18.  
  19.   rMax = 1.0;
  20.   zMin = 0.0;
  21.   zMax =  1.0;
  22.   
  23.   return self;
  24. }
  25.  
  26. - setRMax:(RtFloat)newRMax zMin:(RtFloat)newZMin zMax:(RtFloat)newZMax 
  27.      thetaMax:(RtFloat)newThetaMax
  28.      n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
  29.      printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
  30. {  
  31.    rMax = newRMax;
  32.    if (zMin < 0.0)
  33.    {  NXLogError("warning: clamping zMin of RIBParaboloid to 0.0...\n");
  34.       zMin = 0.0;
  35.    }
  36.    else
  37.    {  zMin = newZMin;
  38.    }
  39.    if (zMax < 0.0)
  40.    {  NXLogError("warning: clamping zMax of RIBParaboloid to 0.0...\n");
  41.       zMax = 0.0;
  42.    }
  43.    else
  44.    {  zMax = newZMax;
  45.    }
  46.    thetaMax = newThetaMax;
  47.   
  48.    [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
  49.  
  50.    dirtyBoundingBox = TRUE;
  51.   
  52.    return self;
  53. }
  54.  
  55. - setRMax:(RtFloat)newRMax { rMax = newRMax; dirtyBoundingBox = TRUE;  return self; }
  56.  
  57. - setZMin:(RtFloat)newZMin 
  58. {  if (zMin < 0.0)
  59.    {  NXLogError("warning: clamping zMin of RIBParaboloid to 0.0...\n");
  60.       zMin = 0.0;
  61.    }
  62.    else
  63.    {  zMin = newZMin; 
  64.    }
  65.    dirtyBoundingBox = TRUE;  
  66.    return self; 
  67. }
  68.  
  69. - setZMax:(RtFloat)newzMax 
  70. {  if (zMax < 0.0)
  71.    {  NXLogError("warning: clamping zMax of RIBParaboloid to 0.0...\n");
  72.       zMax = 0.0;
  73.    }
  74.    else
  75.    {  zMax = newzMax; 
  76.    }
  77.    dirtyBoundingBox = TRUE;  
  78.    return self; 
  79. }
  80.  
  81. - (RtFloat)rMax { return rMax; } 
  82. - (RtFloat)zMin { return zMin; }
  83. - (RtFloat)zMax { return zMax; }
  84.  
  85. - calculateBoundingBoxStartingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
  86. {
  87.   if (thetaMax >= 180.0)
  88.   {   boundingBox[0] =  -1.0 * rMax;
  89.   }
  90.   else  // less than 180
  91.   {  if (thetaMax >= 90.0)
  92.      {  boundingBox[0] =  -1.0 * rMax * (RtFloat)sin((double)(toRadians((thetaMax - 90.0))));
  93.      }
  94.      else
  95.      {  //boundingBox[0] =  rMax * (RtFloat)sin((double)(toRadians(thetaMax)));
  96.         boundingBox[0] = 0.0;  // this is not true if zMax or abs(zMin) is less than rMax
  97.      }
  98.   }
  99.   boundingBox[1] = rMax;
  100.  
  101.   if (thetaMax >= 270.0)
  102.   {  boundingBox[2] = -1.0 * rMax;
  103.      boundingBox[3] = rMax;
  104.   }
  105.   else
  106.   {  if (thetaMax >= 180.0)
  107.      {  boundingBox[2] = rMax * sin((double)(toRadians((thetaMax))));
  108.         boundingBox[3] = rMax;
  109.      }
  110.      else
  111.      {  if (thetaMax >= 90.0)
  112.         {  boundingBox[2] = 0.0;
  113.            boundingBox[3] = rMax;
  114.         }
  115.         else
  116.         {  boundingBox[2] = 0.0;
  117.            boundingBox[3] = rMax * sin((double)(toRadians((thetaMax))));
  118.         }
  119.      }
  120.   }
  121.  
  122.   if (rMax < 0.0)
  123.   {  boundingBox[5] = 0.0;
  124.      boundingBox[4] = rMax;
  125.   }
  126.   else
  127.   {  boundingBox[4] = 0.0;
  128.      boundingBox[5] = rMax;
  129.   }
  130.  
  131.   dirtyBoundingBox = FALSE; 
  132.  
  133.   return self;
  134. }
  135.  
  136.  
  137. - (BOOL)isMoot
  138. {
  139.   if (!rMax) { return YES; }
  140.   if (zMin == zMax) { return YES; }
  141.  
  142.   return [super isMoot];
  143. }
  144.  
  145. - (BOOL)theSameAs:otherRIBCommand
  146. {
  147.   if (rMax != [otherRIBCommand rMax])
  148.   {  return NO;
  149.   }
  150.   if (zMin != [otherRIBCommand zMin])
  151.   {  return NO;
  152.   }
  153.   if (zMax != [otherRIBCommand zMax])
  154.   {  return NO;
  155.   }
  156.  
  157.   return [super theSameAs:otherRIBCommand];
  158. }
  159.  
  160.  
  161. - renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
  162. {
  163.   RiParaboloidV(rMax, zMin, zMax, thetaMax, n, tokens, parms);
  164.  
  165.   return self;
  166. }
  167.  
  168. - (BOOL)isLerpable { return YES; }
  169.  
  170. // note: because we've made the WWSampleList "safe" for having
  171. // multiple samples with the same data, it's perfectly valid to return
  172. // yourself or b
  173. - lerpWith:b by:(float)uValue
  174. {
  175.    id      newMe = nil;
  176.    RtFloat rMaxA, zMinA, zMaxA, thetaMaxA;
  177.    RtFloat rMaxB, zMinB, zMaxB, thetaMaxB;
  178.  
  179.  
  180.    if (([self class] != [b class]) || (uValue <= 0.0))
  181.    {  return self;
  182.    }
  183.  
  184.    if (uValue >= 1.0)
  185.    {  return b;
  186.    }
  187.  
  188.    newMe = [super lerpWith:b by:uValue]; // this makes a copy for us
  189.  
  190.    // okay, now do the specific stuff for this class
  191.    rMaxA = [self rMax];
  192.    rMaxB = [b rMax];
  193.    [newMe setRMax:(rMaxA + ((rMaxB - rMaxA) * uValue))]; 
  194.    zMinA = [self zMin];
  195.    zMinB = [b zMin];
  196.    [newMe setZMin:(zMinA + ((zMinB - zMinA) * uValue))];
  197.    zMaxA = [self zMax];
  198.    zMaxB = [b zMax];
  199.    [newMe setZMax:(zMaxA + ((zMaxB - zMaxA) * uValue))];
  200.    thetaMaxA = [self thetaMax];
  201.    thetaMaxB = [b thetaMax];
  202.    [newMe setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
  203.  
  204.    return newMe;
  205. }
  206.  
  207.  
  208. - lerpSelfWith:b by:(float)uValue
  209. {
  210.    RtFloat rMaxA, zMinA, zMaxA, thetaMaxA;
  211.    RtFloat rMaxB, zMinB, zMaxB, thetaMaxB;
  212.  
  213.  
  214.    if (([self class] != [b class]) || (uValue <= 0.0))
  215.    {  return self;
  216.    }
  217.  
  218.    if (uValue >= 1.0)
  219.    {  return b;
  220.    }
  221.  
  222.    [super lerpSelfWith:b by:uValue]; // this makes a copy for us
  223.  
  224.    // okay, now do the specific stuff for this class
  225.    rMaxA = [self rMax];
  226.    rMaxB = [b rMax];
  227.    [self setRMax:(rMaxA + ((rMaxB - rMaxA) * uValue))]; 
  228.    zMinA = [self zMin];
  229.    zMinB = [b zMin];
  230.    [self setZMin:(zMinA + ((zMinB - zMinA) * uValue))];
  231.    zMaxA = [self zMax];
  232.    zMaxB = [b zMax];
  233.    [self setZMax:(zMaxA + ((zMaxB - zMaxA) * uValue))];
  234.    thetaMaxA = [self thetaMax];
  235.    thetaMaxB = [b thetaMax];
  236.    [self setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
  237.  
  238.    return self;
  239. }
  240.  
  241.  
  242. - writeEve:(NXStream *)stream atTabLevel:(int)tab
  243. {
  244.    int  i;
  245.  
  246.  
  247.    for (i = 0; i < tab; i++)
  248.    {  NXPrintf(stream, "\t");
  249.    }
  250.    NXPrintf(stream, "Paraboloid %f %f %f %f ", rMax, zMin, zMax, thetaMax);
  251.    [super writeParameterList:stream];
  252.    return self;
  253. }
  254.  
  255. - writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
  256. {
  257.    RtFloat umax;
  258.    RtFloat uknots[12];
  259.    RtFloat uk[12] = { 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1.0, 1.0, 1.0};
  260.    RtFloat vmin, vmax;
  261.    RtFloat vknots[6];
  262.    RtFloat vk[6] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0};
  263.    RtFloat uspline[9][4] = { {1.0, 0.0, 1.0, 1.0},
  264.                  {M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  265.                  {0.0, 1.0, 1.0, 1.0},
  266.                  {-M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  267.                  {-1.0, 0.0, 1.0, 1.0},
  268.                  {-M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  269.                  {0.0, -1.0, 1.0, 1.0},
  270.                  {M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  271.                  {1.0, 0.0, 1.0, 1.0}};
  272.    RtFloat vspline[3][4] = { {0.0, 0.0, 0.0, 1.0},
  273.                  {0.5, 0.5, 0.0, 1.0},
  274.                  {1.0, 1.0, 1.0, 1.0}};
  275.    RtFloat r[4];
  276.    int i, j, k;
  277.  
  278.  
  279.    umax = [self thetaMax] / 360.0;
  280.    for (i=0; i<12; i++)
  281.    {  uknots[i] = uk[i] / umax;
  282.    }
  283.  
  284.    vmin = [self zMin] / [self zMax];
  285.    if (vmin < 0.0) vmin = 0.0;
  286.    vmax = 1.0;
  287.    for (i=0; i<6; i++)
  288.    {  vknots[i] = (vk[i] - vmin) / (vmax - vmin);
  289.    }
  290.  
  291.    r[0] = [self rMax];
  292.    r[1] = [self rMax];
  293.    r[2] = [self zMax];
  294.    r[3] = 1.0;
  295.  
  296.    for (i = 0; i < tab; i++)
  297.    {  NXPrintf(stream, "\t");
  298.    }
  299.    NXPrintf(stream, "# ");
  300.    [self writeEve:stream atTabLevel:0];
  301.    NXPrintf(stream, "\n");
  302.  
  303.    for (i = 0; i < tab; i++)
  304.    {  NXPrintf(stream, "\t");
  305.    }
  306.    NXPrintf(stream, "# since Inventor doesn't directly support quadrics in any terribly useful way (sigh), we turn it into a NURBS surface:\n");
  307.  
  308.    for (i = 0; i < tab; i++)
  309.    {  NXPrintf(stream, "\t");
  310.    }
  311.    NXPrintf(stream, "Separator {\n");
  312.  
  313.    for (i = 0; i < (tab+1); i++)  {  NXPrintf(stream, "\t"); }
  314.    NXPrintf(stream, "Coordinate4 {\n");
  315.    for (i = 0; i < (tab+2); i++) {  NXPrintf(stream, "\t"); }
  316.    NXPrintf(stream, "point [");
  317.  
  318.    for (i=0; i<2; i++)
  319.    {  for (j=0; j<9; j++)
  320.       {  if (!i && !j)
  321.          {  NXPrintf(stream, 
  322.              "%f %f %f %f,\n", 
  323.              (r[0] * uspline[j][0] * vspline[i][0]),
  324.              (r[1] * uspline[j][1] * vspline[i][1]),
  325.              (r[2] * uspline[j][2] * vspline[i][2]),
  326.              (r[3] * uspline[j][3] * vspline[i][3]));
  327.       }
  328.          else
  329.          {  NXPrintf(stream, 
  330.              "       %f %f %f %f,\n", 
  331.              (r[0] * uspline[j][0] * vspline[i][0]),
  332.              (r[1] * uspline[j][1] * vspline[i][1]),
  333.              (r[2] * uspline[j][2] * vspline[i][2]),
  334.              (r[3] * uspline[j][3] * vspline[i][3]));
  335.       }
  336.          for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  337.       }
  338.    }
  339.    for (j=0; j<8; j++)
  340.    {  NXPrintf(stream, 
  341.                "       %f %f %f %f,\n", 
  342.                (r[0] * uspline[j][0] * vspline[i][0]),
  343.                (r[1] * uspline[j][1] * vspline[i][1]),
  344.                (r[2] * uspline[j][2] * vspline[i][2]),
  345.                (r[3] * uspline[j][3] * vspline[i][3]));
  346.      for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  347.    }
  348.    NXPrintf(stream, 
  349.         "       %f %f %f %f]\n", 
  350.         (r[0] * uspline[j][0] * vspline[i][0]),
  351.         (r[1] * uspline[j][1] * vspline[i][1]),
  352.         (r[2] * uspline[j][2] * vspline[i][2]),
  353.         (r[3] * uspline[j][3] * vspline[i][3]));
  354.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  355.    NXPrintf(stream, "}\n");
  356.  
  357.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  358.    NXPrintf(stream, "NurbsSurface {\n");
  359.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  360.    NXPrintf(stream, "numUControlPoints 9\n");
  361.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  362.    NXPrintf(stream, "numVControlPoints 2\n");
  363.  
  364.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  365.    NXPrintf(stream, "uKnotVector [");
  366.    for (i=0; i<11; i++)
  367.    {    NXPrintf(stream, "%f, ", uknots[i]);
  368.    }
  369.    NXPrintf(stream, "%f]\n", uknots[i]);
  370.  
  371.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  372.    NXPrintf(stream, "vKnotVector [");
  373.    for (i=0; i<3; i++)
  374.    {    NXPrintf(stream, "%f, ", vknots[i]);
  375.    }
  376.    NXPrintf(stream, "%f]\n", vknots[i]);
  377.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  378.    NXPrintf(stream, "}\n");
  379.    for (k = 0; k < tab; k++) {  NXPrintf(stream, "\t"); }
  380.    NXPrintf(stream, "}\n");
  381.  
  382.    return self;
  383. }
  384.  
  385.  
  386. #define typeVector "fff"
  387. #define typeValues &rMax, &zMin, &zMax
  388.  
  389. - read:(NXTypedStream*)stream 
  390. {
  391.     int version;
  392.     [super read:stream];
  393.  
  394.     version = NXTypedStreamClassVersion(stream,"RIBParaboloid");
  395.     if (version == 0) NXReadTypes(stream,"i",&version), version=1;
  396.     if (version == 1)
  397.     {  NXReadTypes(stream,typeVector,typeValues);
  398.     } 
  399.     else 
  400.     {
  401.     }
  402.     return self;
  403. }
  404.  
  405. - write:(NXTypedStream*)stream 
  406. {
  407.     [super write:stream];
  408.  
  409.     NXWriteTypes(stream,typeVector, typeValues);
  410.  
  411.     return self;
  412. }
  413.  
  414.  
  415. @end
  416.